package com.cmii.sjw.department.control.jsc.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cmii.sjw.department.control.common.AccessTokenFetcher;
import com.cmii.sjw.department.control.jsc.mapper.SchoolMapMapper;
import com.cmii.sjw.department.control.jsc.mapper.SchoolMapper;
import com.cmii.sjw.department.control.jsc.model.HigherEducationVo;
import com.cmii.sjw.department.control.jsc.model.School;
import com.cmii.sjw.department.control.jsc.model.SchoolInfAnalysisVo;
import com.cmii.sjw.department.control.jsc.model.SchoolInfo;
import com.cmii.sjw.department.control.jsc.model.base.SchoolData;
import com.cmii.sjw.department.control.jsc.model.params.SchoolInfoParams;
import com.cmii.sjw.department.control.jsc.service.SchoolService;
import com.cmii.sjw.department.control.jsc.util.Result;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.*;


@Slf4j
@Service
public class SchoolServiceImpl extends ServiceImpl<SchoolMapper, School> implements SchoolService {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private SchoolMapMapper schoolMapMapper;

    private final ObjectMapper objectMapper = new ObjectMapper();


    // 接口URL列表
    private final String[] apiUrls = {
            "http://23.210.23.13:9000/edu-data-management/api/v1/broker/api/22",
    };

    /**
     * 学校数量统计
     *
     * @return 获取json数据
     */
    @Override
    public SchoolData getData() {
        try {
            String accessToken = new AccessTokenFetcher().fetchAccessToken();
            log.info("使用的访问令牌: {}", accessToken);

            HttpHeaders headers = new HttpHeaders();
            headers.set("X-Auth-Token", accessToken);
            headers.setContentType(MediaType.APPLICATION_JSON);

            int page = 1;
            int pageSize = 100;
            String url = apiUrls[0] + "?page=" + page + "&pageSize=" + pageSize;

            HttpEntity<?> entity = new HttpEntity<>(headers);

            ResponseEntity<String> response = restTemplate.exchange(
                    url,
                    HttpMethod.GET,
                    entity,
                    String.class
            );

            if (response.getStatusCode().is2xxSuccessful()) {
                String responseBody = response.getBody();
                JsonNode jsonNode = objectMapper.readTree(responseBody);

                SchoolData schoolData = new SchoolData()

                        .setTotalCount(jsonNode.path("totalCount").asInt());

                JsonNode resultsNode = jsonNode.path("results");
                if (resultsNode.isArray()) {
                    List<School> schools = new ArrayList<>();
                    School totalData = null;
                    for (JsonNode resultNode : resultsNode) {
                        School school = new School()
                                .setId(resultNode.path("id").asText())
                                .setAreaCode(resultNode.path("area_code").asText())
                                .setAreaName(resultNode.path("area_name").asText())
                                .setAreaLevel(resultNode.path("area_level").asText())
                                .setTeachersTotalNumber(resultNode.path("teachers_total_number").asText())
                                .setSchoolsTotalNumber(resultNode.path("schools_total_number").asText())
                                .setStudentsTotalNumber(resultNode.path("students_total_number").asText());

                        schools.add(school);
                        // 获取重庆市的总数据
                        if ("50".equals(school.getAreaCode())) {
                            totalData = school;
                        }
                    }
                    schoolData.setResults(schools);
                    schoolData.setTotalData(totalData);

                } else {
                    log.error("响应中未找到有效的结果: {}", responseBody);
                    throw new RuntimeException("响应中未找到有效的结果");
                }

                return schoolData;
            } else {
                log.error("HTTP 请求返回: {} {}", url, response.getStatusCodeValue());
                throw new RuntimeException("API 请求返回状态码异常");
            }
        } catch (Exception e) {
            log.error("API调用失败 {}: {}", apiUrls[0], e.getMessage(), e);
            throw new RuntimeException("API 调用失败", e);
        }
    }

    /**
     * 学校地图详细
     * @param params
     * @return
     */
    @Override
    public Result schoolMapDetailed(SchoolInfoParams params) {

        Map<String, Object> result = new HashMap<>();
        //查询重庆市默认查询全部
        if("重庆市".equals(params.getAreaName())) params.setAreaName(null);
        // 获取学校列表
        List<SchoolInfo> schoolList = getSchoolList(params);
        // 获取高等学校详细
        List<HigherEducationVo> higherEducationVoList = schoolMapMapper.getHigherEducationList(params.getAreaName(),params.getAreaCode());
        // 获取学校数量
        List<SchoolInfAnalysisVo> schoolQuantityList = schoolMapMapper.getSchoolQuantityList(params.getAreaName(),params.getAreaCode());
        // 获取学校信息分析
        List<SchoolInfAnalysisVo> schoolInfAnalysisList = schoolMapMapper.getSchoolInfAnalysisList(params.getAreaName(),params.getAreaCode());


        result.put("schoolList", schoolList);
        result.put("higherEducationVoList", higherEducationVoList);
        result.put("schoolQuantityList", schoolQuantityList);
        result.put("schoolInfAnalysisList", schoolInfAnalysisList);

        return Result.success(result);
    }

    /**
     * 获取学校列表
     * @param params
     * @return
     */
    private List<SchoolInfo> getSchoolList(SchoolInfoParams params) {
        List<SchoolInfo> schoolList = null;
        if (!areAllFieldsNull(params)){
            LambdaQueryWrapper<SchoolInfo> schoolInfoQueryWrapper = new LambdaQueryWrapper<>();

            if (StringUtils.isNotBlank(params.getName())) {
                schoolInfoQueryWrapper.like(SchoolInfo::getName, params.getName());
            }
            addConditionIfPresent(schoolInfoQueryWrapper, SchoolInfo::getManagementAreaName, params.getAreaName());
            addConditionIfPresent(schoolInfoQueryWrapper, SchoolInfo::getAreaCode, params.getAreaCode());
            addConditionIfPresent(schoolInfoQueryWrapper, SchoolInfo::getSchoolLevelCode, params.getSchoolLevelCode());
            addConditionIfPresent(schoolInfoQueryWrapper, SchoolInfo::getSchoolLevel, params.getSchoolLevel());
            addConditionIfPresent(schoolInfoQueryWrapper, SchoolInfo::getStageSubTypeCode, params.getStageSubTypeCode());
            addConditionIfPresent(schoolInfoQueryWrapper, SchoolInfo::getStageSubType, params.getStageSubType());
            addConditionIfPresent(schoolInfoQueryWrapper, SchoolInfo::getPhdPoint, params.getPhdPoint());

            schoolList = schoolMapMapper.selectList(schoolInfoQueryWrapper);
        }
        return schoolList;
    }

    /**
     * 判断字段是否为空，如果不为空则添加查询条件
     * @param wrapper
     * @param column
     * @param value
     */
    private void addConditionIfPresent(LambdaQueryWrapper<SchoolInfo> wrapper, SFunction<SchoolInfo, ?> column, String value) {
        if (StringUtils.isNotBlank(value)) {
            wrapper.eq(column, value);
        }
    }

    /**
     * 判断所有字段是否都为空
     * @return 如果所有字段都为空则返回true，否则返回false
     */
    public boolean areAllFieldsNull(SchoolInfoParams params) {
        if (params == null) {
            return true;
        }

        List<String> fields = Arrays.asList(
                params.getName(),
                params.getAreaName(),
                params.getAreaCode(),
                params.getSchoolLevelCode(),
                params.getSchoolLevel(),
                params.getStageSubTypeCode(),
                params.getStageSubType(),
                params.getPhdPoint()
        );

        return fields.stream().allMatch(StringUtils::isEmpty);
    }

}